
/*
 XMail OSAX -- Copyright (C) 2004, 2005, 2006, 2007 Jean-Baptiste LE STANG osax@lestang.org
 
	
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
#include "Osax.h"
#include "AEDescUtils.h"

/* Here you may want to include your own C files */
#include "XMail.h"
#include "Terminology.h"

/* See Osax.h for instructions  */
EventDescription gEventDescriptionList[]={
    {kMailSuite,kMailSend,0},
    {kMailSuite,kMailSendRaw,1},
    {kMailToolBoxSuite,'mate',2},
    {kMailToolBoxSuite,'matn',3},	
    {kMailToolBoxSuite,'maen',4},
    {kMailToolBoxSuite,'maqp',5},
    {kMailToolBoxSuite,'mams',6},
    {kMailToolBoxSuite,'mauf',7},
    {kMailToolBoxSuite,'date',8},
    {kMailToolBoxSuite,'mime',9},
    {kMailToolBoxSuite,'mtod',10},
    {kMailToolBoxSuite,'lien',11},
    {kMailToolBoxSuite,'fing',12},
    {kMailToolBoxSuite,'enco',13},
};


int gEventDescriptionCount=sizeof(gEventDescriptionList)/sizeof(EventDescription);

extern "C" static CFBundleRef getBundle();

static int signals[] = {
    SIGALRM, SIGBUS, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGABRT, SIGQUIT, SIGSEGV, SIGTRAP, SIGTERM, SIGVTALRM, SIGXCPU, SIGXFSZ, -1
};

void removeErrorTrapping();
void handleErrorTrapping(int signal);
void installErrorTrapping();

void WritePropertyList(CFPropertyListRef propertyList,CFURLRef fileURL ) {
	CFDataRef xmlData = NULL;
	Boolean status = false;
	SInt32 errorCode = 0;
	xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, propertyList );
	if (xmlData != NULL) {
		status = CFURLWriteDataAndPropertiesToResource (fileURL,xmlData,NULL,&errorCode); 
		CFRelease(xmlData);
	}
}
void handleErrorTrapping(int signal){
    #pragma unused(signal)
    /* URL du bundle de losax*/
    CFURLRef bundle = CFBundleCopyBundleURL(getBundle());
    /* Info de l'osax qui crashe */
    CFDictionaryRef osaxInfo = CFBundleGetInfoDictionary(getBundle());
    /* URL de l'application de crash reporting*/
    CFURLRef url = CFBundleCopyResourceURLInDirectory (bundle,CFSTR("CrashDiscoveryGUI"),CFSTR("app"),NULL);
    /* BUnlde de l'application utilisant l'oasx qui a crashe*/
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    /* INfo de l'application crashante*/
    CFDictionaryRef info = CFBundleGetInfoDictionary(mainBundle);
    /* recuperation du nom de l'exe qui a crashe*/
    CFStringRef executable = (CFStringRef)CFDictionaryGetValue(info,CFSTR("CFBundleExecutable"));
    /* identifier de l'osax qui a crashe*/
    CFStringRef osaxName = (CFStringRef)CFDictionaryGetValue(osaxInfo,CFSTR("CFBundleIdentifier"));
    /* version de l'osax qui a crashe*/
    CFStringRef osaxVersion = (CFStringRef)CFDictionaryGetValue(osaxInfo,CFSTR("CFBundleVersion"));
    
    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
    CFDictionaryAddValue(dict,CFSTR("product"),osaxName);
    CFDictionaryAddValue(dict,CFSTR("version"),osaxVersion);
    CFDictionaryAddValue(dict,CFSTR("application"),executable);
    CFDateRef date = CFDateCreate(NULL,CFAbsoluteTimeGetCurrent());
    CFDictionaryAddValue(dict,CFSTR("date"),date);
  
    FSRef foundRef;
    OSErr err = FSFindFolder (kUserDomain ,kTemporaryFolderType ,kCreateFolder,&foundRef);
    if (err == noErr){
        CFURLRef dest = CFURLCreateFromFSRef (NULL,&foundRef);
        CFURLRef log =  CFURLCreateCopyAppendingPathComponent(NULL,dest,CFSTR("CrashReporterGUI.log"),false);
        WritePropertyList(dict,log);
        CFRelease(dest);
        CFRelease(log);
        LSOpenCFURLRef(url,NULL);
    }
    
    CFRelease(date);
    CFRelease(bundle);
    CFRelease(url);
}

void removeErrorTrapping(){
    struct sigaction action;
    action.__sigaction_u.__sa_handler = SIG_DFL;
    for( int i = 0; signals[i] != -1; ++i ) sigaction( signals[i], &action, NULL );
}

void installErrorTrapping(){
    struct sigaction action;
    memset(&action,0,sizeof(struct sigaction));
    action.__sigaction_u.__sa_handler = handleErrorTrapping;
    action.sa_flags = SA_RESETHAND | SA_SIGINFO | SA_NODEFER;
    sigemptyset(&action.sa_mask);
    for( int i = 0; signals[i] != -1; ++i ) sigaction( signals[i], &action, NULL );
}

pascal OSErr OsaxEventHandler(const AppleEvent* message, AppleEvent* reply, long refCon){
    OSErr err = noErr;
    //installErrorTrapping();
    switch(refCon){
        case 0 : err = SendMailHandler(message, reply,refCon);break;
        case 1 : err = SendRawMailHandler(message, reply,refCon);break;
        case 2 : err = MatchNameHandler(message,reply,refCon);break;
        case 3 : err = MatchEmailHandler(message,reply,refCon);break;
        case 4 : err = EncodeEmailHandler(message,reply,refCon);break;
        case 5 : err = QuotedPrintableHandler(message,reply,refCon);break;
        case 6 : err = EncodeMimeStyleHandler(message,reply,refCon);break;
        case 7 : err = UnicodeFindHandler(message,reply,refCon);break;
        case 8 : err = RFC822DateHandler(message,reply,refCon);break;
        case 9 : err = MimeBoundHandler(message,reply,refCon);break;
        case 10 : err = MimeOfFileHandler(message,reply,refCon);break;
        case 11 : err = GetListOfEncodingsHandler(message,reply,refCon);break;
        case 12 : err = FingerSMTPServerHandler(message,reply,refCon);break;
        case 13 : err = GetListOfMacOSXEncodingsHandler(message,reply,refCon);break;
        default:err = errAEEventNotHandled;
    }
    //removeErrorTrapping();
    return err;
}
